/**
 * 文件子元素相关中间件
 *
 * Created by snowingsea on 2020/03/06.
 */
const functions = require('./../../models/functions');
const projectVersions = require('./../../models/project-versions');
const projects = require('./../../models/projects');
const files = require('./../../models/files');
const fileElements = require('./../../models/file-elements');
const PhoenixError = require('./../../models/phoenix-error');

/**
 * 判断URL参数中元素Id是否存在
 * @param req
 * @param res
 * @param next
 */
function requireFileElementExist(req, res, next) {
  const fileElementId = req.body.fileElementId || req.params.fileElementId;
  // switch (req.method) {
  //   case 'POST':
  //     fileElementId = req.body.fileElementId;
  //     break;
  //   case 'GET':
  //   case 'DELETE':
  //     fileElementId = req.params.fileElementId;
  //     break;
  //   default:
  //     break;
  // }
  if (!fileElementId) {
    next(new PhoenixError('invalid request', 'Missing parameters. "fileElementId" is required'));
    return;
  }
  functions.getFunction(fileElementId)
    .then((fileElement) => {
      if (!fileElement) {
        return Promise.reject(new PhoenixError('not found', 'Not found, file element not found'));
      }
      req.$fileElement = fileElement;
      const { projectId, versionId, fileId } = fileElement;
      const promises = [
        projects.getProject(projectId),
        projectVersions.getVersion(versionId),
        files.getFile(fileId),
      ];
      return Promise.all(promises);
    })
    .then(([project, projectVersion, file]) => {
      if (!projectVersion) {
        return Promise.reject(new PhoenixError('not found', 'Not found, projectVersion not found'));
      }
      if (!project) {
        return Promise.reject(new PhoenixError('not found', 'Not found, project not found'));
      }
      req.$project = project;
      req.$projectVersion = projectVersion;
      req.$file = file;
      return Promise.resolve();
    })
    .then(() => {
      next();
    })
    .catch((err) => {
      next(new PhoenixError(err));
    });
}

/**
 * 判断元素是否是模板元素
 * @param req
 * @param res
 * @param next
 */
function requireTemplateElement(req, res, next) {
  if (!fileElements.isTemplateElement(req.$fileElement.kind)) {
    next(new PhoenixError('precondition failed', 'require template element'));
  }
  next();
}

/**
 * 判断元素是否是特化元素
 * @param req
 * @param res
 * @param next
 */
function requireSpecialElement(req, res, next) {
  if (!fileElements.isSpecialElement(req.$fileElement.kind)) {
    next(new PhoenixError('precondition failed', 'require special element'));
  }
  next();
}

/**
 * 判断特化内容是否重复
 * @param req
 * @param res
 * @param next
 */
function checkDuplicateSpecialization(req, res, next) {
  const specializedData = fileElements.prepareSpecialData(req.$fileElement, req.body);
  fileElements.getSpecializedElements(req.$fileElement)
    .then((specializedElements) => {
      specializedElements.forEach((specializedElement) => {
        if (!specializedElement.templateParamsData) {
          return;
        }
        if (JSON.stringify(specializedElement.templateParamsData)
          === JSON.stringify(specializedData)) {
          next(new PhoenixError('conflict', []));
        }
      });
      return Promise.resolve();
    })
    .then(() => {
      next();
    });
}

/**
 * Export model definition object.
 */
module.exports = {
  requireFileElementExist,
  requireTemplateElement,
  requireSpecialElement,
  checkDuplicateSpecialization,
};
